package ro.msg.quiz.repository;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ro.msg.quiz.domain.MultipleChoiceQuestion;
import ro.msg.quiz.domain.Question;
import ro.msg.quiz.domain.Quiz;
import ro.msg.quiz.domain.SingleChoiceQuestion;
import ro.msg.quiz.domain.TextQuestion;
import ro.msg.quiz.exception.MyException;
import ro.msg.quiz.validator.IValidator;
import ro.msg.quiz.validator.MultipleChoiceQuestionValidator;
import ro.msg.quiz.validator.SingleChoiceQuestionValidator;
import ro.msg.quiz.validator.TextQuestionValidator;

//AUTHOR: Ervin

//Class responsible for getting data from text files, validating data and populating a map
public class Populater {
    // Map<Integer, Quiz> = pairs of <id quiz, quiz>
    private Map<Integer, Quiz> quizMap;
    private IValidator<Question> questionValidator;

    public Populater() throws Exception {
	quizMap = new HashMap<Integer, Quiz>();
	this.readQuizzes("quiz.txt");
	this.populateQuizMap("quizQuestions.txt", "questions.txt");
    }

    /**
     * @return the quizMap
     */
    public Map<Integer, Quiz> getQuizMap() {
	return quizMap;
    }

    private void readQuizzes(String file) throws Exception {
	BufferedReader buffer = new BufferedReader(new FileReader(file));
	String line = "";
	while ((line = buffer.readLine()) != null) {
	    String[] x = line.split("\\s");// split at space
	    Quiz quiz = new Quiz(Integer.parseInt(x[0]), x[1]);
	    quizMap.put(Integer.parseInt(x[0]), quiz);
	}
	buffer.close();
    }

    private void populateQuizMap(String fileQuizQuestions, String fileQuestions) throws Exception {
	BufferedReader buffer1 = new BufferedReader(new FileReader(fileQuizQuestions));
	BufferedReader buffer2 = new BufferedReader(new FileReader(fileQuestions));

	String line2 = buffer2.readLine();
	List<String> questionListOfStrings = new ArrayList<String>();
	while (line2 != null) {
	    questionListOfStrings.add(line2);
	    line2 = buffer2.readLine();
	}
	buffer2.close();

	String line1 = "";
	String[] x = new String[2];

	while ((line1 = buffer1.readLine()) != null) {
	    x = line1.split("\\s");
	    Question question = this.createQuestion(questionListOfStrings.get(Integer.parseInt(x[1]) - 1));
	    quizMap.get(Integer.parseInt(x[0])).addQuestion(question);
	}

	buffer1.close();
    }

    // returns a valid question from a string which was read from the file
    // questions.txt
    private Question createQuestion(String s) throws MyException {
	Question question;

	String[] s1 = s.split("\\s", 2);
	String[] x = s1[1].split("\\s\'|\'\\s\'|\'\\s|\'");

	int idQuestion, correctIndex, nrOfOptions, i;
	String text, answer;
	List<String> options = new ArrayList<String>();
	List<Integer> correctIndexes = new ArrayList<Integer>();

	idQuestion = Integer.parseInt(s1[0]);
	nrOfOptions = x.length - 3;

	if (x[0].equals("1")) {
	    text = x[1];

	    for (i = 0; i < nrOfOptions; i++)
		options.add(x[i + 2]);

	    correctIndex = Integer.parseInt(x[nrOfOptions + 2].trim());

	    question = new SingleChoiceQuestion(idQuestion, text, options, correctIndex);
	    this.questionValidator = new SingleChoiceQuestionValidator();
	    this.questionValidator.validate(question);
	} else if (x[0].equals("2")) {
	    text = x[1];

	    for (i = 0; i < nrOfOptions; i++)
		options.add(x[i + 2]);

	    String[] opt = x[nrOfOptions + 2].split("\\s");
	    for (int j = 0; j < opt.length; j++)
		correctIndexes.add(Integer.parseInt(opt[j]));

	    question = new MultipleChoiceQuestion(idQuestion, text, options, correctIndexes);
	    this.questionValidator = new MultipleChoiceQuestionValidator();
	    this.questionValidator.validate(question);
	} else {
	    text = x[1];
	    answer = x[nrOfOptions + 2];

	    question = new TextQuestion(idQuestion, text, answer);
	    this.questionValidator = new TextQuestionValidator();
	    this.questionValidator.validate(question);
	}

	return question;
    }
}
